var path = require('path');
var schedule = require('node-schedule');
var waterfall = require('async/waterfall');
var DbCommon = require('./db');
var fecha = require('fecha');
const Article = require('./article');
const ArticleCategory = require('./articleCategory');
var request = require('request-promise');
var log4js = require(path.resolve(__dirname, '../config/logger'));
var logger = log4js.getLogger('status');
var util = require('./util');
const Observer = require('./observe');
const categoryOptions = require('./categoryOptions');
var axios = require("axios");
axios.defaults.timeout = 30000;
const isInWhiteList = function (category) {
  var whiteList = [12, 15, 16, 17, 18, 19, 23]
  let ret = false
  for (let index = 0; index < whiteList.length; index++) {
    const v = whiteList[index]
    if (v === category) {
      ret = true
      break
    }
  }
  return ret;
}
const getLRStocks = function (date) {
  return new Promise(function (resolve, reject) {
    let options = {
      method: 'POST',
      uri: 'http://query.wedengta.com/query',
      body: {
        "call": "kudu",
        "func": "dw_machine_write.app_t_margin_stat_stock_daily",
        "conds": [
          [{
            "k": "trading_day",
            "op": "=",
            "v": date
          }],
          []
        ]
      },
      json: true
    }
    request(options).then(function (res) {
      if (res.code == 0) {
        let data = res.data;
        let resData = [];
//      logger.info(data, "两融个股接口数据");
        resolve(data);
      } else {
        reject(new Error('get liangrong stocks error'));
      }
    }).catch(function (error) {
  		console.log(error);
  		reject(error)
    })
  })
}

const checkTradeDate = function () {
  return new Promise(function (resolve, reject) {
    console.log('checkTradeDate');
    axios({
      method: 'GET',
      url: 'https://sec.wedengta.com/getMarketQuotation?action=tradingtime'
    }).then(function (res) {
      console.log('checkTradeData返回res',res)
      if (res.status == 200) {
        data = res.data;
        console.log("res.data",res.data);
        var now = JSON.parse(data.content).iNow;
        var list = JSON.parse(data.content).vTradingTimeDesc;
        var isInTradeDate = false;
        var d = new Date(now * 1000);
        var s = fecha.format(d, 'yyyy-MM-dd');
        for (var index = 0; index < list.length; index++) {
          var element = list[index];
          if (element.eMarketType == 0 && element.eTradingDealType == 0 && element.iOpenTime) {
            var de = new Date(element.iOpenTime * 1000);
            if (fecha.format(de, 'yyyy-MM-dd') == s) {
              isInTradeDate = true;
              break;
            }
          }
        }
        resolve({
          isInTrade: isInTradeDate
        })
      } else {
        reject(new Error(res.msg))
      }
    }).catch(function (error) {
      reject(error);
    })
  })
}
const getLastTradeDate = function () {
  return new Promise(function (resolve, reject) {
    //let time = Date.now() - 20 * 60 * 60 * 1000;
    let time = Date.now();
    let date = fecha.format(new Date(time), 'YYYY-MM-DD');
//  let date = '2019-04-01';
    let options = {
      method: 'POST',
      url: 'http://query.wedengta.com/query',
      data: {
        "call": "kudu",
        "func": "dw_common.app_work_day",
        "conds": [
          [{
            "k": "cld_date",
            "op": "=",
            "v": date
          }],
          []
        ]
      },
    }
    console.log("getLastTradeDate请求options",options)
    axios(options).then(function (res) {
      console.log("getLastTradeDate返回",res);
      if (res.status == 200) {
        let data = res.data.data[0];
        console.log("axios.data.data[0]",res.data.data[0]);
        //logger.info(data);
        resolve(data);
      } else {
        reject(new Error('getLastTradeDate error'));
      }
    }).catch(function (error) {
      reject(error)
    })
  })
}
const resolveYinHeArticle = function (articleCategory, options) {
  if (typeof articleCategory.template == 'string') {
    articleCategory.template = JSON.parse(articleCategory.template);
  }
  articleCategory.title = articleCategory.template.title;
  articleCategory.contents = articleCategory.template.contents;
	logger.info('articleCategory:' + JSON.stringify(articleCategory));
  return function () {
    var tryTimes = 20
    var compile = function () {
      Observer.clear();
      var date = new Date();
      console.log('date',date);
      getLastTradeDate().then(function (res) {
        var lastDate = res.last_wk_dt;
        //let date = fecha.format(new Date(time), 'YYYYMMDD');
        let params = {
          //trade_day: '2018-10-24',
          trade_day: fecha.format(date, 'YYYY-MM-DD'),
          trading_day: lastDate
        }
        if (options && options instanceof Object) {
          params = Object.assign(params, options);
        }
        if (articleCategory.category == 6 || articleCategory.category == 9) {
          params.min = 930
        }
        if (articleCategory.category == 7 || articleCategory.category == 5 || articleCategory.category == 10) {
          params.min = 1130
        }
        if (articleCategory.category == 8 || articleCategory.category == 13 || articleCategory.category == 11) {
          params.min = 1500
        }
        if (articleCategory.category == 20) {
          params.min = 1000
        }
        if (articleCategory.category == 21) {
          params.min = 1100
        }
        if (articleCategory.category == 22) {
          params.min = 1400
        }
        let force = false;
        if (options) {
          force = options.force;
        }
        // 两融个股先获取龙虎榜
        if (articleCategory.category == 23) {
          //let time = Date.now()- 20 * 60 * 60 * 1000;
          //let date = fecha.format(new Date(time), 'YYYY-MM-DD');
          getLRStocks(lastDate).then(function (res) {
            var index = 0;
            var length = res.length;
            var singleCompile = function () {
              Observer.clear();
              if (index == length) {
                return;
              }
              var item = res[index];
              var singleParams = Object.assign({
                date: item.date,
                dt_code: item.dt_code,
                name: item.sec_name,
              }, params);
//            logger.info('singleParams:' + JSON.stringify(singleParams));
              //{"dt_code":"0001000823","name":"超声电子","trade_day":"2019-03-27","trading_day":"2019-03-26"}
              let article = new Article({
                id: articleCategory.id,
                name: articleCategory.name,
                channel: articleCategory.channel,
                template: articleCategory.template,
                title: articleCategory.title,
                contents: articleCategory.contents,
                status: articleCategory.status,
                autoParams: singleParams
              })
              article.compile({
                  force: force
                }).then(function (res) {
//                logger.info(article.titleContent);
                  var verified = 0;
                  if (isInWhiteList(articleCategory.category)) {
                    verified = 1;
                  }
                  DbCommon.addOrEditOrDelete({
                    form: {
                      name: article.name,
                      category: articleCategory.category,
                      channel: articleCategory.channel,
                      code: singleParams.dt_code,
                      sec_name: singleParams.name.replace(/\s+/g,""),
                      title: article.titleContent.replace(/\s+/g,""),
                      content: article.content.replace(/\s+/g,""),
                      verified: verified,
                      updater: articleCategory.updater
                    },
                    tableName: 'news'
                  }).then(function (result) {
//                  logger.info('add news result: ' + JSON.stringify(result));
                    var news_id = result.insertId;
                    var channels = articleCategory.channel.split(',');
                    var news_channels = [];
                    for (var i = 0; i < channels.length; i++) {
                      var channel_id = channels[i];
                      news_channels.push([news_id, Number(channel_id), new Date()])
                    }
                    DbCommon.batchAddNewsChannel({
                      form: news_channels,
                      tableName: 'auto_news_channel'
                    }).then(function (result) {
//                    logger.info('add news_channels result: ' + JSON.stringify(result));
                      logger.info(JSON.stringify(singleParams) + '--' + singleParams.name + '--' + article.name + ' generate success ' + '操作人' + articleCategory.updater);
                      index++;
                      // 没编译一个股票文章需要清一下全局上下文
                      Observer.clear();
                      singleCompile(index);
                    })
                  })
                }).catch(function (error) {
                  index++;
                  // 没编译一个股票文章需要清一下全局上下文
                  Observer.clear();
                  singleCompile(index);
                  console.log(error.message);
                });
            }
            singleCompile();
          }).catch(function (err) {
            Observer.clear();
            console.log(err.message);
          })
        } else {
          let article = new Article({
            id: articleCategory.id,
            name: articleCategory.name,
            channel: articleCategory.channel,
            template: articleCategory.template,
            title: articleCategory.title,
            contents: articleCategory.contents, //[{ "id": 255, "name": "主力资金测试","status": 1}, {"id": 255,"name": "主力资金测试","status": 1}]
            status: articleCategory.status,
            autoParams: params
          })
          article.compile({
              force: force
            }).then(function (res) {
//          	logger.info(article.content);
              var verified = 0;
              if (isInWhiteList(articleCategory.category)) {
                verified = 1;
              }
              DbCommon.addOrEditOrDelete({
                form: {
                  name: article.name,
                  category: articleCategory.category,
                  channel: articleCategory.channel,
                  code: params.sec_code || '',
                  sec_name: params.sec_name || '',
                  title: article.titleContent,
                  content: article.content,
                  verified: verified
                },
                tableName: 'news'
              }).then(function (result) {
//              logger.info('add news result: ' + JSON.stringify(result));
                var news_id = result.insertId;
                var channels = articleCategory.channel.split(',');
                var news_channels = [];
                for (var i = 0; i < channels.length; i++) {
                  var channel_id = channels[i];
                  news_channels.push([news_id, Number(channel_id), new Date()])
                }
                DbCommon.batchAddNewsChannel({
                  form: news_channels,
                  tableName: 'auto_news_channel'
                }).then(function (result2) {
//                logger.info('add news_channels result: ' + JSON.stringify(result2));
                  logger.info(JSON.stringify(params) + '--' + article.name + ' generate success ');
                  Observer.clear();
                })

              })
            })
            .catch(function (error) {
              Observer.clear();
              console.log(error.message);
            });
        }
      }).catch(function(err){
        console.log('getLastTrade错误',err);
        if(tryTimes--){
          console.log(`还有 ${tryTimes} 次尝试`)
          compile();
        }else{
          console.log("尝试次数已用完");
        }
      })
    }
    compile();
  }
}
const compileMethod = function (articleCategory, options) {
	if(articleCategory.status == 1){
		resolveYinHeArticle(articleCategory, options)()
	} else {
		logger.info('失效文章不编译：' + articleCategory.name + articleCategory.status)
	}
}
const tasks = [
  function (callback) {
    DbCommon.getDataById({
      table: 'article'
    }).then(function (data) {
      callback(null, data)
    }).catch(function (error) {
      callback(error, [])
    });
  },
  function (data, callback) {
    let res = data.filter((item) => {
      return item.status == 1;
    });
    callback(null, res);
  }
]

var timerIdMaps = {};

module.exports = {
  startSchedule: function (time, articleId) {
    logger.info('添加定时任务: ' + time + ' article: ' + articleId);
    let arrs = time.split(':');
    time = `${arrs[2]} ${arrs[1]} ${arrs[0]} * * *`;
//  console.log(timerIdMaps);
    if (timerIdMaps[articleId]) {
      timerIdMaps[articleId].cancel();
    }
    timerIdMaps[articleId] = schedule.scheduleJob(time, function () {
      logger.info(time + '定时器任务启动');
      console.log('timeIdMaps:',timerIdMaps)
      logger.info('定时器任务启动文章id',articleId);
      var articleCategory = new ArticleCategory(articleId);
      console.log('定时器任务启动文章对象',articleCategory);
      articleCategory.init().then(function () {
        console.log('定时器任务启动文章对象init后',articleCategory);
      	if(articleCategory.status == 1){
           // promise重试
           function retry(fn, times){
            return new Promise((resolve, reject)=>{
                function run(){
                    fn().then(resolve).catch(err=>{
                        if(times--){
                          console.log(`还有 ${times} 次尝试`)
                          run();
                        }else{
                          reject(err)
                        }
                    })
                }
                run()
            })
          };
	        retry(checkTradeDate,20).then(function (res) {
            console.log("checkTradeDate 返回",res)
	          // 全部日期  1; 交易日期  2; 非交易日期 3
	        	if (articleCategory.publish_date == 1) {
	        		compileMethod(articleCategory, null);
	        	};
	          if (articleCategory.publish_date == 2 && res.isInTrade) {
	          	if(articleCategory.publish_day){  //1,2,3,4,5
		        		let week = new Date().getDay();
		          	let rightWeek = false;
		          	let arr = articleCategory.publish_day.split(',');
		          	arr.forEach(item => {
		          		if(item == week){
		          			rightWeek = true;
		          		}
		          	});
		          	if (rightWeek) {
		          		compileMethod(articleCategory, null);
			          } else {
			          	logger.info(time + '定时器任务终止+交易日具体日期不符');
			          }
	          	} else {
	          		logger.info('这是交易日文章');
	          		compileMethod(articleCategory, null);
	          	}
	          } else if (articleCategory.publish_date == 3 && !res.isInTrade) {
	          	compileMethod(articleCategory, null);
	          }
	        }).catch(function (err) {
	          logger.info(err);
            console.log('checkTradeDate catch');
	        })
      	} else {
      		logger.info('失效文章不编译：' + articleCategory.name + articleCategory.status);
      	}
      })
    })
  },
  compileArticleCategoryBySingleStock: function (articleCategory, options) {
    return new Promise(function (resolve, reject) {
      if (typeof articleCategory.template == 'string') {
        articleCategory.template = JSON.parse(articleCategory.template);
      }
      articleCategory.title = articleCategory.template.title;
      articleCategory.contents = articleCategory.template.contents;
      let params = {
        date: options.date,
        dt_code: options.dt_code,
        name: options.name
      }
      let article = new Article({
        id: articleCategory.id,
        name: articleCategory.name,
        channel: articleCategory.channel,
        template: articleCategory.template,
        title: articleCategory.title,
        contents: articleCategory.contents,
        status: articleCategory.status,
        autoParams: params
      })
      article.compile().then(function (res) {
          logger.info(article.titleContent);
          resolve(article.content);
        })
        .catch(function (error) {
          Observer.clear();
          reject(error);
        });
    })
  },
  compileArticleCategory: function (articleCategory, options) {
  	compileMethod(articleCategory, options);
  },
  getLastTradeDay: function() {
    getLastTradeDate();
  },
  test: function () {
    waterFallTasks()
  },
  resolveYinHeArticle: function (articleCategory, options) {
	  if (typeof articleCategory.template == 'string') {
	    articleCategory.template = JSON.parse(articleCategory.template);
	  }
	  articleCategory.title = articleCategory.template.title;
	  articleCategory.contents = articleCategory.template.contents;
		logger.info('articleCategory:' + JSON.stringify(articleCategory));
		return new Promise(function (resolve, reject) {
      var tryTimes = 20
	    var compile = function () {
	      Observer.clear();
	      var date = new Date();
        console.log('date',date);
	      getLastTradeDate().then(function (res) {
	        var lastDate = res.last_wk_dt;
	        let params = {
	          trade_day: fecha.format(date, 'YYYY-MM-DD'),
	          trading_day: lastDate
	        }
	        if (options && options instanceof Object) {
	          params = Object.assign(params, options);
	        }
	        if (articleCategory.category == 6 || articleCategory.category == 9) {
	          params.min = 930
	        }
	        if (articleCategory.category == 7 || articleCategory.category == 5 || articleCategory.category == 10) {
	          params.min = 1130
	        }
	        if (articleCategory.category == 8 || articleCategory.category == 13 || articleCategory.category == 11) {
	          params.min = 1500
	        }
	        if (articleCategory.category == 20) {
	          params.min = 1000
	        }
	        if (articleCategory.category == 21) {
	          params.min = 1100
	        }
	        if (articleCategory.category == 22) {
	          params.min = 1400
	        }
	        let force = false;
	        if (options) {
	          force = options.force;
	        }
	        // 两融个股先获取龙虎榜
	        if (articleCategory.category == 23) {
	          getLRStocks(lastDate).then(function (res) {
	            var index = 0;
	            var length = res.length;
	            var singleCompile = function () {
	              Observer.clear();
	              if (index == length) {
	              	resolve('编译完成')
	                return
	              }
	              var item = res[index];
	              var singleParams = Object.assign({
	                date: item.date,
	                dt_code: item.dt_code,
	                name: item.sec_name,
	              }, params);
	              let article = new Article({
	                id: articleCategory.id,
	                name: articleCategory.name,
	                channel: articleCategory.channel,
	                template: articleCategory.template,
	                title: articleCategory.title,
	                contents: articleCategory.contents,
	                status: articleCategory.status,
	                autoParams: singleParams
	              })
	              article.compile({
	                  force: force
	                }).then(function (res) {
	                  var verified = 0;
	                  if (isInWhiteList(articleCategory.category)) {
	                    verified = 1;
	                  }
	                  DbCommon.addOrEditOrDelete({
	                    form: {
	                      name: article.name,
	                      category: articleCategory.category,
	                      channel: articleCategory.channel,
	                      code: singleParams.dt_code,
	                      sec_name: singleParams.name,
	                      title: article.titleContent,
	                      content: article.content,
	                      verified: verified,
	                      updater: articleCategory.updater
	                    },
	                    tableName: 'news'
	                  }).then(function (result) {
	                    var news_id = result.insertId;
	                    var channels = articleCategory.channel.split(',');
	                    var news_channels = [];
	                    for (var i = 0; i < channels.length; i++) {
	                      var channel_id = channels[i];
	                      news_channels.push([news_id, Number(channel_id), new Date()])
	                    }
	                    DbCommon.batchAddNewsChannel({
	                      form: news_channels,
	                      tableName: 'auto_news_channel'
	                    }).then(function (result) {
	                      logger.info(JSON.stringify(singleParams) + '--' + singleParams.name + '--' + article.name + ' generate success ' + '操作人' + articleCategory.updater);
	                      index++;
	                      // 没编译一个股票文章需要清一下全局上下文
	                      Observer.clear();
	                      singleCompile(index);
	                    })
	                  })
	                }).catch(function (error) {
	                  index++;
	                  // 没编译一个股票文章需要清一下全局上下文
	                  Observer.clear();
	                  singleCompile(index);
	                  console.log(error.message);
	                  reject(error);
	                });
	            }
	            singleCompile();
	          }).catch(function (err) {
	            Observer.clear();
	            console.log(err.message);
	            reject(err);
	          })
	        } else {
	          let article = new Article({
	            id: articleCategory.id,
	            name: articleCategory.name,
	            channel: articleCategory.channel,
	            template: articleCategory.template,
	            title: articleCategory.title,
	            contents: articleCategory.contents, //[{ "id": 255, "name": "主力资金测试","status": 1}, {"id": 255,"name": "主力资金测试","status": 1}]
	            status: articleCategory.status,
	            autoParams: params
	          })
	          article.compile({
	              force: force
	            }).then(function (res) {
	//          	logger.info(article.content);
	              var verified = 0;
	              if (isInWhiteList(articleCategory.category)) {
	                verified = 1;
	              }
	              DbCommon.addOrEditOrDelete({
	                form: {
	                  name: article.name,
	                  category: articleCategory.category,
	                  channel: articleCategory.channel,
	                  code: params.sec_code || '',
	                  sec_name: params.sec_name || '',
	                  title: article.titleContent,
	                  content: article.content,
	                  verified: verified
	                },
	                tableName: 'news'
	              }).then(function (result) {
	                var news_id = result.insertId;
	                var channels = articleCategory.channel.split(',');
	                var news_channels = [];
	                for (var i = 0; i < channels.length; i++) {
	                  var channel_id = channels[i];
	                  news_channels.push([news_id, Number(channel_id), new Date()])
	                }
	                DbCommon.batchAddNewsChannel({
	                  form: news_channels,
	                  tableName: 'auto_news_channel'
	                }).then(function (result2) {
	                  logger.info(JSON.stringify(params) + '--' + article.name + ' generate success ');
	                  Observer.clear();
	                  resolve('编译完成')
	                })
	
	              })
	            }).catch(function (error) {
	              Observer.clear();
	              console.log(error.message);
	              reject(error);
	            })
	        	}
	      }).catch(function(err){
          console.log('getLastTrade错误',err);
          if(tryTimes--){
            console.log(`还有 ${tryTimes} 次尝试`)
            compile();
          }else{
            console.log("尝试次数已用完");
          }
        })
	    }
	    compile();
			})
	}
}